$(document).ready(function() {

	var PAGE_SIZE = 25;
	
	var sort = 'title';
	var busy_count = 0;

	$(window).bind('hashchange', function() {
		var search = $.bbq.getState('q');
		var sort = $.bbq.getState('sort');
		var kind = $.bbq.getState('kind');
		var offset = $.bbq.getState('offset');
		var problems = $.bbq.getState('problems');
		
		$('#search-text').val(search);
		$('#search-kind').val(kind);
		
		fetchDataFromServer(search, kind, sort, problems, offset);
	});

	function refreshData() {
		fetchData($('#search-text').val(), getLibraryKind(), sort, $('#search-problem-count').val(), 0);
	}

	function fetchData(search, kind, sort, problems, offset) {
		var state = { q : search || '' };
		if(kind) {
			state.kind = kind;
		}
		
		sort || (sort = 'title');
		
		if(sort != 'title') {
			state.sort = sort;
		}
		
		if(offset > 0) {
			state.offset = offset;
		}

		if(problems) {
			state.problems = problems;
		}
		
		$.bbq.pushState(state, 2);
	}
	
	$(window).trigger('hashchange');
	
	$('#sort-title').click(function() {
		if(sort != 'title') {
			sort = 'title';
			refreshData();
		}
		return false;
	});

	$('#sort-tested').click(function() {
		if(sort != 'tested') {
			sort = 'tested';
			refreshData();
		}
		return false;
	});

	$('#search-text').typeWatch({
		captureLength: 0,
		callback: function() {
			refreshData();
		}
	});

	$('#custom-title').typeWatch({
		wait: 1,
		callback: function() {
			if(!editingSite) {
				setNameFromTitle();
			}
		}
	});

	$('#library-kind').change(function() {
		refreshData();
	});

	function getLibraryKind() {
		return $('#library-kind').val();
	}
		
	$('#search-problem-count').change(function() {
		refreshData();
	});
	
	$('#add-library').click(function() {
		showCustomForm(null, true);
		return false;
	});
	
	var $tbody = $('#search-results tbody');
	
	function beginAjax() {
		if(busy_count == 0) {
			$('#search-results').addClass('busy');
		}		
		busy_count++;
	}
	
	function endAjax() {
		busy_count--;
		if(busy_count == 0) {
			$('#search-results').removeClass('busy');
		}
	}

	function fetchDataFromServer(search, kind, sort, problems, offset) {
		var url = '/library/search';

		beginAjax();
		jQuery.ajax({

			url: url,
			
			data: {
				q: search,
				offset: offset,
				sort: sort,
				kind: kind,
				limit: PAGE_SIZE,
				problems: problems
			},

			success: function(data, textStatus, jqXHR) {
				updateTable($.parseJSON(jqXHR.responseText));
				endAjax();
			},

			error: function(jqXHR, textStatus, errorThrown) {
				endAjax();
			}
		});
	}
	
	function saveData(data, serverValidate) {
		var url = '/admin/save';

		beginAjax();
		var siteToDelete = editingSite;
		var deleteOnServer = (editingSite && editingSite.is_community && !data.is_community);
		
		jQuery.ajax({

			url: url,
			
			type: 'POST',
			
			data: data,

			success: function(ajaxData, textStatus, jqXHR) {
				if(siteToDelete) {
					if(deleteOnServer) {
						deleteSite(siteToDelete);
					} else {
						deleteRow(siteToDelete);
					}
				}
				var lib = addDataRow(data, true);
				if(serverValidate) {
					validateSite(lib);
				}
				endAjax();
			},

			error: function(jqXHR, textStatus, errorThrown) {
				alert(textStatus + "\n\n" + jqXHR.responseText);
				endAjax();
			}
		});
	}
	
	function deleteSite(site) {
		var url = '/admin/delete/' + site.name;

		beginAjax();
		jQuery.ajax({

			url: url,
			
			success: function(data, textStatus, jqXHR) {
				deleteRow(site);
				endAjax();
			},

			error: function(jqXHR, textStatus, errorThrown) {
				alert(textStatus + "\n\n" + jqXHR.responseText);
				endAjax();
			}
		});
	}
	
	function validateSite(site) {
		var url = '/admin/validate/' + site.name;

		beginAjax();
		jQuery.ajax({

			url: url,
			
			success: function(data, textStatus, jqXHR) {
				data = $.parseJSON(jqXHR.responseText);
				if(data.error) {
					alert(data.error);
				} else {
					deleteRow(site);
					addDataRow(data.library, true);
				}
				endAjax();
			},

			error: function(jqXHR, textStatus, errorThrown) {
				alert(textStatus + "\n\n" + jqXHR.responseText);
				endAjax();
			}
		});
	}
	
	function editLibrary() {
		$('#custom-form').show();
		$('#search-form').hide();
		return false;
	}
	
	function updateTable(results) {
		var libs = results.items;
		var $title = $('#search-results-title');

		var info = '';
		if(results.query) {
			info = "'" + results.query + "'";
		}		
		info += " [" + (results.offset + 1) + " - " + (results.offset + libs.length) + " of " + results.count + "]";
		$('title').text('BookBurrito Library Database (Admin): ' + info);
		$title.text("Search Results: " + info);
		
		$('#sorting').attr('class', "sort_" + results.sort);
		
		var $pager = buildPager(results, function(results, offset, title) {
			return $('<a href="#"/>')
				.html(title)
				.attr('title', (offset + 1) + "...")
				.data('offset', offset)
				.click(function() {
					fetchData(results.query, results.kind, results.sort, results.problems, offset);
					return false;
				});
		}, PAGE_SIZE);
		
		$title.append($pager);
		
		$tbody.empty();
		for(var i = 0; i < libs.length; i++) {
			var data = libs[i];
			addDataRow(data);
		}
	}

	function deleteRow(site) {
		$('#search-results tbody tr').each(function() {
			var $tr = $(this);
			if($tr.data('row') == site) {
				$tr.remove();
			}
		});		
	}

	function addDataRow(data, highlight) {
		var lib = new Library(data);
		var cls = data.tested ? (data.problems ? "error" : "ok") : "disabled";
		var $tr = $('<tr/>')
			.data('row', lib)
			.append($('<td/>').html(
				$('<a>')
					.text(lib.title)
					.attr('href', lib.link.replace('#{ISBN}', lib.have))
			).attr('class', data.is_community ? 'community' : 'validated'))
			.append($('<td/>').attr("class", cls).html(data.tested
				? $('<span class="timeago"/>').attr('title', data.tested).attr('ts', data.tested)
				: "Not tested"))
			.append($('<td/>')
				.append($('<a href="#"/>').text("Edit").click(function() {
					var site = $(this).parents('tr').data('row');
					showCustomForm(site, false);
					return false;
				}))
				.append($('<a href="#"/>').text("Clone").click(function() {
					var site = $(this).parents('tr').data('row');
					showCustomForm(site, true);
					return false;
				}))
				.append($('<a href="#"/>').text("Delete").click(function() {
					var site = $(this).parents('tr').data('row');
					if(confirm("Do you want to delete '" + site.title + "' (" + site.name + ")?")) {
						deleteSite(site);
					}
					return false;
				}))
				.append($('<a href="#"/>').text("Validate").click(function() {
					var site = $(this).parents('tr').data('row');
					validateSite(site);
					return false;
				}))
			);
		$tbody.append($tr);

		$('.timeago', $tr).timeago();
		
		if(highlight) {
			var title = lib.title;
			var name = lib.name;
			$($('tr', $tbody).get().reverse()).each(function() {
				var row = $(this).data('row');
				if(row.title > title
					|| (row.title == title && row.name > name)) {
					$tr.insertBefore($(this));
				}
			});
			
			$($tr).effect("highlight", { color: "#99ff66" }, 2000);
		}
		
		return lib;
	}

	$('#add_custom').click(function(e) {
		e.stopPropagation();
		showCustomForm();
		return false;
	});
	
	$('#custom-cancel').click(function(e) {
		e.stopPropagation();
		hideCustomForm();
		return false;
	});
	
	function setNameFromTitle() {
		var title = $('#custom-title').val().toLowerCase();
		
		// Set the country
		var country = "us";
		var result = title.match(/^\[(..)\]/);
		if(result && result.length > 0) {
			country = result[1];
			title = title.substr(4);
		}
		
		// Substitue non-letter characters
		title = title.replace(/\&/, "and");
		
		// Strip whitespace
		title = title.replace(/[^\w]+/g, " ");
		title = title.replace(/^\s+/, "");
		title = title.replace(/\s+$/, "");
		title = title.replace(/\s+/, " ");
		
		var library_name = title.indexOf(' ');
		var state = title.substr(0, library_name);
		var library = title.substr(library_name + 1).replace(/ /g, '_');
		
		var name = country + "." + state + "." + library;
		
		$('#custom-name').val(name);
	}

	$('#custom-link').typeWatch({
		captureLength: 0,
		callback: updateAllLinkInfo
	});

	$('#custom-have').typeWatch({
		captureLength: 0,
		callback: function() {
			updateLinkInfo($('#custom-have'));
		}
	});
	
	$('#set-name-from-title').click(setNameFromTitle);
	
	$('#custom-match_isbn, #custom-match_missing').click(function() {
		if(matchByIsbn()) {
			$('#field-missing').hide();
		} else {
			$('#field-missing').show();
			$('#custom-missing').focus();
		}
	});
	
	$('#custom-save').click(function(e) {
		e.stopPropagation();

		if(validateAndSave()) {
			hideCustomForm();
		}
		return false;
	});
	
	$('#custom-save-validate').click(function(e) {
		e.stopPropagation();

		if(validateAndSave(true)) {
			hideCustomForm();
		}
		return false;
	});
	
	$('#custom-save-validate-next').click(function(e) {
		e.stopPropagation();
		
		var nextSite, prevRow;
		$($('tr', $tbody).get().reverse()).each(function() {
			var row = $(this).data('row');
			if(row.name == editingSite.name) {
				nextSite = prevRow;
			}
			prevRow = row;
		});
		
		if(validateAndSave(true)) {
			if(nextSite) {
				editingSite = nextSite;
				putCustomDataToControls(editingSite);
			} else {
				hideCustomForm();
			}
		}
		return false;
	});
	
	
	function validateAndSave(serverValidate) {
		var data = getCustomData();
		
		function isMatch(text, regex) {
			var result = text.match(regex);
			return (result && result.length > 0);
		}
		
		// Validate Title
		if(isMatch(data.title, /^\s*$/)) {
			alert("Lirary Title may not be blank");
			$('#custom-title').focus();
			return false;
		}
		
		// Validate Link
		if(!isMatch(data.link, /\#\{ISBN\}/)) {
			alert("Link must contain #{ISBN} token!");
			$('#custom-link').focus();
			return false;
		}
		
		// Check for duplicates
		var duplicate = null;
		$('#custom table.matrix tbody tr').each(function() {
			var row =$(this).data('row');
			if(row && row != editingSite && row.name == data.name) {
				duplicate = row;
			}
		});
		if(duplicate) {
			alert("Library name '" + data.name + "' is not unique!\n\n"
				+ "Library '" + duplicate.title + "' is named the same.");
			$('#custom-name').focus();
			return false;
		}		

		saveData(data, serverValidate);
		
		return true;
	}
	
	function customKeyUp(e) {
		  if (e.keyCode == 27) { $('#custom-cancel').click(); }   // esc
	}
	
	function hideCustomForm() {
		$(document).unbind('keyup', customKeyUp);
		$('#search-form').show();
		$('#custom-form').hide();
	}
	
	var editingSite = null;
	
	function showCustomForm(site, duplicate) {
		$('#search-form').hide();
		$('#custom-form .test-results').hide();
		
		if(site != null) {
			putCustomDataToControls(site);
			if(duplicate) {
				site = null;
			}
		}
		
		if(!site) {
//			$('#custom-name').val(uuid());
		}
		
		editingSite = site;
		$('#custom-form').show();
		
		$(document).bind('keyup', customKeyUp);
	}

	function putCustomDataToControls(site) {
		var data = site._data;
		$('#custom-form input:text').each(function(){
			var name =$(this).attr('name');
			if(data[name]) {
				$(this).val(data[name]);
			}
		});
		matchByIsbn(data.match_isbn || false);
		isCommunityLibrary(data.is_community);
		updateAllLinkInfo();
	}
	
	function fetchTest() {
		var url = '/admin/test';

		var data = {
			name: $('#custom-name').val(),
			title: $('#custom-title').val(),
			link: $('#custom-link').val(),
			have: $('#custom-have').val(),
			dont: $('#custom-dont').val()
		};
		
		if(matchByIsbn()) {
			data.match_isbn = true;
		} else {
			data.missing = $('#custom-missing').val()
		}

		beginAjax();
		jQuery.ajax({

			url: url,
			
			data: data,

			success: function(data, textStatus, jqXHR) {
				updateTable($.parseJSON(jqXHR.responseText));
				endAjax();
			},

			error: function(jqXHR, textStatus, errorThrown) {
				endAjax();
			}
		});
	}
	

	$('#custom-test').click(function() {
		var data = getCustomData();
		
		var site = new CustomLibrary(data);
				
		var $test = $('#custom-form .test-results').text('').removeClass('succeeded').removeClass('failed').show();
		
		var trace = function(msg) {
			$test.html($test.html() + msg + "\n");
		};
		
		trace("Testing configuration for '" + site.title + "'...");
		
		testLibrary();

		var finishedTest = function(error) {
			$test.addClass(error ? 'failed' : 'succeeded');
		};
		
		
		var traceResult = function(type, isbn, url, found, expectedBook) {
			var cssClass = found != expectedBook ? 'error' : 'success';
			trace("Search for <b>" + type + "</b> book <a href='" + url + "'>" + isbn + "</a> returned: <span class='" + cssClass + "'>" + (found ? "yes" : "no") + "</span> "
			 + (found ? "(book found)" : "(book not found)"));
		};

		
		function testLibrary() {

			var url = '/admin/test';
	
			var data = {
				name: $('#custom-name').val(),
				title: $('#custom-title').val(),
				link: $('#custom-link').val(),
				have: $('#custom-have').val(),
				dont: $('#custom-dont').val(),
				is_community: isCommunityLibrary()
			};
			
			if(matchByIsbn()) {
				data.match_isbn = true;
			} else {
				data.missing = $('#custom-missing').val()
			}
	

			jQuery.ajax({
	
				url: url,
				
				data: data,
	
				success: function(data, textStatus, jqXHR) {
					var reply = $.parseJSON(jqXHR.responseText);
					var failed = false;
					
					if(reply.error) {
						trace("ERROR: " + reply.error);
						failed = true;
					} else {
						traceResult("existing", reply.library.have, reply.haveUrl, reply.have, true);
						traceResult("missing", reply.library.dont, reply.dontUrl, reply.dont, false);
						if(reply.existing) {
							if(!editingSite || editingSite.name != reply.library.name) {
								trace("<span class='error'>A library record with this name already exists!</span>");
							}
						} else {
							if(editingSite) {
								if(editingSite.name != reply.library.name) {
									if(editingSite.is_community && !reply.library.is_community) {
										trace("<span class='success'>Verified library: the library record will be changed from community to verified!</span>");
									} else {
										trace("<span class='error'>Changed library name: a new library record will be created!</span>");
									}
								}
							} else {
								trace("<span class='success'>Name for new library is unique.</span>");
							}
						}
						failed = !reply.have || reply.dont;
					}
					
					finishedTest(failed);
				},
	
				error: function(jqXHR, textStatus, errorThrown) {
					trace(message + " failed: " + textStatus);
					finishedTest(true);
				}
			});
		}
		
		return false;
	});

});


/*
	Callbacks used by edit-library.js
*/
function getCustomData() {
	var data = {};
	$('#custom-form input:text').each(function(){
		data[$(this).attr('name')] = $(this).val();
	});

	data["is_community"] = isCommunityLibrary();
	
	if(matchByIsbn()) {
		data.match_isbn = true;
		delete(data.missing);
	}
	
	return data;
};

function isCommunityLibrary(val) {
	if(val) {
		$('#custom-kind-community').click();
		$('#custom-kind-community').click();
	} else if(val === false) {
		$('#custom-kind-validated').click();		
		$('#custom-kind-validated').click();		
	} else {
		return $('#custom-kind-community').attr('checked');
	}
};
